package com.ruoyi.web.controller.app;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.JwtUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@Api("用户操作")
@RestController
@RequestMapping("/api/account")
public class AccountController extends BaseController{

	@Autowired
	private ISysUserService sysUserService;

	@Autowired
	private SysPasswordService passwordService;

	@ApiOperation(value = "用户登录", notes = "密码需要加密发送")
	@ApiImplicitParams({@ApiImplicitParam(name = "userName", value = "登录账号", required = true, dataType = "String"), @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String")})
	@ApiResponses({@ApiResponse(code = 400, message = "请求参数异常"),})
	@PostMapping("/login")
	@ResponseBody
	public AjaxResult login(String userName, String password, HttpServletResponse response) throws Exception{
		// 必填项验证
		if(StringUtils.isEmpty(userName)){
			throw new BusinessException("账号不能为空");
		}
		if(StringUtils.isEmpty(password)){
			throw new BusinessException("密码不能为空");
		}
		// 用户名及密码校验
		UsernamePasswordToken token = new UsernamePasswordToken(userName, password, false);
		Subject subject = SecurityUtils.getSubject();
		try{
			// 执行UserRealm登录验证
			subject.login(token);
			// 登录成功，完成签名
			SysUser appUser = sysUserService.selectUserByLoginName(userName);
			String jwtToken = JwtUtil.sign(userName, JwtUtil.SECRET);
			response.setHeader(JwtUtil.AUTH_HEADER, jwtToken);
			Map<String, String> resultMap = new HashMap<String, String>();
			resultMap.put("access_token", jwtToken);
			resultMap.put("refresh_token", jwtToken);
			resultMap.put("userId", appUser.getUserId().toString());
			resultMap.put("userName", appUser.getUserName());
			resultMap.put("loginName", appUser.getLoginName());
			resultMap.put("token", subject.getSession().getId().toString());
			resultMap.put("currentDate", DateUtils.parseDateToStr("yyyy年MM月dd日", new Date()));
			return success(resultMap);
		}catch(AuthenticationException e){
			String msg = "用户或密码错误";
			if(StringUtils.isNotEmpty(e.getMessage())){
				msg = e.getMessage();
			}
			return error(msg);
		}
	}

	@ApiOperation(value = "修改密码", notes = "密码需要加密发送")
	@ApiImplicitParams({@ApiImplicitParam(name = "password", value = "原密码", required = true, dataType = "String"), @ApiImplicitParam(name = "newPassword", value = "新密码", required = true, dataType = "String"),
			@ApiImplicitParam(name = "newPassword1", value = "确认密码", required = true, dataType = "String")})
	@ApiResponses({@ApiResponse(code = 400, message = "请求参数异常"),})
	@PostMapping("/updatePassword")
	@ResponseBody
	public AjaxResult updatePassword(String password, String newPassword, String newPassword1, HttpServletResponse response) throws Exception{
		// 必填项验证
		if(StringUtils.isEmpty(password)){
			throw new BusinessException("密码不能为空");
		}
		if(StringUtils.isEmpty(newPassword)){
			throw new BusinessException("新密码不能为空");
		}
		if(StringUtils.isEmpty(newPassword1)){
			throw new BusinessException("确认密码不能为空");
		}
		if(!newPassword.equals(newPassword1)){
			throw new BusinessException("新密码两次密码输入不一致");
		}
		SysUser user = ShiroUtils.getSysUser();
		user.setPassword(newPassword);
		sysUserService.checkUserAllowed(user);
		user.setSalt(ShiroUtils.randomSalt());
		user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
		if(sysUserService.resetUserPwd(user) > 0){
			if(ShiroUtils.getUserId().longValue() == user.getUserId().longValue()){
				ShiroUtils.setSysUser(sysUserService.selectUserById(user.getUserId()));
			}
			return success();
		}
		return error();
	}

	@ApiOperation(value = "用户退出")
	@PostMapping("/logout")
	@ResponseBody
	public AjaxResult logout(SysUser sysUser){
		SecurityUtils.getSubject().logout();
		return AjaxResult.success("loginout");
	}

	/**
	 * 批量初始化账号密码为admin123
	 * 
	 * @throws Exception
	 */
	// @GetMapping("/changePassword")
	@ResponseBody
	public AjaxResult changePassword() throws Exception{
		SysUser user = new SysUser();
		List<SysUser> userList = sysUserService.selectUserList(user);
		for(SysUser user1 : userList){
			String password = passwordService.encryptPassword(user1.getLoginName(), "admin123", user1.getSalt());
			SysUser newUser = new SysUser();
			newUser.setUserId(user1.getUserId());
			newUser.setPassword(password);
			sysUserService.updateUserInfo(newUser);
		}
		return AjaxResult.success(1);

	}

}
